#include "fbrestore.h"
#define RESPBUF	1024

FBRestore::FBRestore()
{
}
FBRestore::~FBRestore()
{
}

void FBRestore::set_config( QString back_file_,
                            QString out_file_,
                            QString user_,
                            QString pass_,
                            QString serv_name_,
                            bool verbose_ )
{
back_file_ba = back_file_.toLatin1();
back_file = (char *) back_file_ba.data();

out_file_ba = out_file_.toLatin1();
out_file = (char *) out_file_ba.data();

user_ba = user_.toLatin1();
user = (char *) user_ba.data();

pass_ba = pass_.toLatin1();
pass = (char *) pass_ba.data();

serv_name_ba = serv_name_.toLatin1();
serv_name = (char *) serv_name_ba.data();

verbose = verbose_;
}

void FBRestore::run()
{

ISC_STATUS status[20];
isc_svc_handle svc_handle = 0L;
char svc_name[RESPBUF];
char spb_buff[RESPBUF];
char thd_buff[RESPBUF];
char sendbuf[] = {isc_info_svc_line};
char respbuf[RESPBUF];
char * p = respbuf;
char * spb = spb_buff;
char * thd = thd_buff;
char * x;
int spblen;
int thdlen;
unsigned long options;

/////////////////////////////
//
//  SPB
//

// Version
*spb++ = isc_spb_version;
*spb++ = isc_spb_current_version;

// User
*spb++ = isc_spb_user_name;
*spb++ = (char) strlen (user);
for ( x = user; *x; )
{
*spb++ = *x++;
}
// Password
*spb++ = isc_spb_password;
*spb++ = (char) strlen(pass);
for ( x = pass; *x; )
{
*spb++ = *x++;
}

//
//
////////////////////////////////////////

spblen = spb - spb_buff;

sprintf (svc_name, serv_name);

isc_service_attach( status,
                    0,
                    svc_name,
                    &svc_handle,
                    (unsigned short) spblen,
                    spb_buff );

    if ( (int) status[0] == 1 && status[1] )
    {
    char err_buff[768];
    err_buff[0] = 'E';
    err_buff[1] = 'r';
    err_buff[2] = 'r';
    err_buff[3] = 'o';
    err_buff[4] = 'r';
    err_buff[5] = ':';
    err_buff[6] = ' ';
    ISC_STATUS * status_p = &status[0];
    isc_interprete ( &err_buff[7], &status_p );
    emit log_line( QString(err_buff) + QString("\n") );
    return;
    }                    

////////////////////////////////////////
//
//  Service request block
//

// Action byte
*thd++ = isc_action_svc_restore;

//
// Backup file
//
*thd++ = isc_spb_bkp_file;
// 2 bytes length of argument
int back_l = strlen(back_file);
int l2 = isc_vax_integer( (char *) &back_l, 2 );
char * d2 = (char *) &l2;
*thd++ = *d2++;
*thd++ = *d2++;
// Argument (backup file)
    for (x = back_file; *x;)
    {
    *thd++ = *x++;
    }

//
// DB name
//
*thd++ = isc_spb_dbname;
// 2 bytes length of argument
int dbname_l = strlen(out_file);
int l1 = isc_vax_integer( (char *) &dbname_l, 2 );
char * d1 = (char *) &l1;
*thd++ = *d1++;
*thd++ = *d1++;
// Argument (database name)
    for ( x = out_file; *x; )
    {
    *thd++ = *x++;
    }

// Verbose
    if ( true == verbose )
    {
    *thd++ = isc_spb_verbose;
    }

// Restore options
*thd++ = isc_spb_options;
options = isc_spb_res_replace;
ADD_SPB_NUMERIC(thd, options);

//
//
///////////////////////////////////////////////////////

thdlen = thd - thd_buff;

emit log_line(QString("Attach succeed\n"));

isc_service_start( status,
                   &svc_handle,
                   NULL,
                   (unsigned short) thdlen,
                   thd_buff );

    if ( (int) status[0] == 1 && status[1] )
    {
    char err_buff[768];
    err_buff[0] = 'E';
    err_buff[1] = 'r';
    err_buff[2] = 'r';
    err_buff[3] = 'o';
    err_buff[4] = 'r';
    err_buff[5] = ':';
    err_buff[6] = ' ';
    ISC_STATUS * status_p = &status[0];
    isc_interprete ( &err_buff[7], &status_p );
    emit log_line( QString(err_buff) + QString("\n") );

    isc_service_detach (status, &svc_handle);
    return;
    } 

emit log_line( QString("Restore is running ...\n") );

    do
    {
    QString output;
    isc_service_query ( status,
                        &svc_handle,
                        NULL,
                        0,
                        NULL,
                        sizeof(sendbuf),
                        sendbuf,
                        RESPBUF,
                        respbuf );

        if ( (int) status[0] == 1 && status[1])
        {
        char err_buff[768];
        err_buff[0] = 'E';
        err_buff[1] = 'r';
        err_buff[2] = 'r';
        err_buff[3] = 'o';
        err_buff[4] = 'r';
        err_buff[5] = ':';
        err_buff[6] = ' ';
        ISC_STATUS * status_p = &status[0];
        isc_interprete ( &err_buff[7], &status_p );
        emit log_line( QString(err_buff) + QString("\n") );
        
        isc_service_detach (status, &svc_handle);
        return;
        }

    x = p = respbuf;

        if (*p++ == isc_info_svc_line)
        {
        ISC_USHORT len = 0;
        ISC_USHORT chTmp = 0;
        
        len = (ISC_USHORT)isc_vax_integer(p, sizeof(ISC_USHORT));
        p += sizeof (ISC_USHORT);

            if (!len)
            {
                if (*p ==  isc_info_data_not_ready)
                {
                output.append( QString("No data available now\n") );
                continue;
                }
                else
                {
                    if (*p != isc_info_end)
                    {
                    output.append( QString("Format error .. ") );
                    output.append( QString::number(*p) );
                    output.append( QString("\n") );
                    }
                break;
                }
            }

            for ( chTmp = 0; chTmp < len; chTmp++ )
            {
            output.append( QString( p[chTmp] ) );
            }

        p += len;

            if ( *p != isc_info_truncated && *p != isc_info_end )
            {
            output.append( QString("Format error ... ") );
            output.append( QString::number(*p) );
            output.append( QString("\n") );
            break;
            }
        }
        else
        {
        output.append( QString( "Not a isc_info_svc_line ") );
        output.append( QString::number(*x) );
        output.append( QString("\n") );
        }
    //emit log_line(output);
    } while ( *x == isc_info_svc_line );
isc_service_detach( status, &svc_handle );
emit log_line( QString("Finished.\n") );
}
